/**
 * 
 */
package hamsterwrench.data.lump;

import java.io.*;

/**
 * @author Matthias Lamers - some elements borrowed from OHRRPGCE-FMF
 *
 */
public class LumpExtractor {
	private static final long[] PDP_OFFSETS = {256*256, 256*256*256, 1, 256};

	private File lump;
	private File outFile;
	private BufferedInputStream dis;
	private String lumpDir;
	private FileWriter fw;
	private boolean eof;

	public LumpExtractor(File i){
		lump = i;
		try {
			dis = new BufferedInputStream(new FileInputStream(lump));
			outFile = new File(lump.getParent() + File.separatorChar + "temp");
			outFile.mkdir();
			lumpDir = outFile.getAbsolutePath() + File.separatorChar;
			System.out.println("LumpExtractor ready.");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public void extract(){
		eof = false;
		String filename;
		long len;
		try{
			while(!eof){
				filename = getName();
				if(eof){
					System.out.println("done.");
					break;
				}
				len = getLength();
				outFile = new File(lumpDir + filename);
				fw = new FileWriter(outFile);
				for(long i=0; i < len; i++){
					int c = dis.read();
					if(c != -1){
						fw.write((char)c);
					}else{
						System.err.println("ERROR: Reached EOF too early!");
						break;
					}
				}
				System.out.println("Extracted " + filename + ", length " + len + " bytes." );
				fw.close();
			}
		}catch(IOException e){
			System.err.println("Something went wrong:");
			e.printStackTrace();
		}
	}

	private String getName() throws IOException {

		StringBuilder sb = new StringBuilder(16);
		for (byte c=readByte(); c!='\0'; c = readByte()) {
			sb.append((char)c);
		}

		return sb.toString();
	}

	private byte readByte() {
		byte[] c = new byte[]{'\0'};
		try {
			if (dis.read(c, 0, 1)<1)
				eof = true;
			return c[0];
		} catch (IOException iex) {
			eof = true;
			return 0;
		}
	}

	private long getLength() throws IOException {
		long result = 0;
		for (int i=0; i<PDP_OFFSETS.length; i++) {
			result += (PDP_OFFSETS[i] * dis.read());
		}
		return result;
	}

	public void destroy(){
		try {
			dis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
